﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;
using Microsoft.WindowsAzure.Storage.RetryPolicies;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;

namespace AWSS3ToAzureBlob
{
    [ExcludeFromCodeCoverage]
    class AzureStorageBlobFacade : IAzureStorageBlobFacade
    {
        CloudBlobClient _client = null;
        CloudBlobContainer _container = null;

        public bool Initialize(string azureStorageAccount, string azureStorageKey, string azureStorageContainer)
        {
            bool returnValue = false;

            try
            {
                StorageCredentials credential = new StorageCredentials(azureStorageAccount,
                    azureStorageKey);

                CloudStorageAccount account = new CloudStorageAccount(credential, true);
                
                _client = account.CreateCloudBlobClient();
                _client.RetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(2), 10);

                _container = _client.GetContainerReference(azureStorageContainer);
                
                returnValue = _container.Exists();
            }
            catch (Exception ex)
            {
                TraceHelper.TraceError(ex.Message);
            }

            return returnValue;
        }

        public string StartCopy(string blobName, string sourceUrl)
        {
            CloudBlockBlob blob = _container.GetBlockBlobReference(blobName);
            return blob.StartCopyFromBlob(new Uri(sourceUrl));
        }

        public CopyState[] GetPendingCopies()
        {
            List<CopyState> returnValue = new List<CopyState>();

            var blobs = _container.ListBlobs(null, 
                true, 
                BlobListingDetails.Copy);

            foreach (var item in blobs)
            {
                var blob = item as ICloudBlob;

                if (blob.CopyState.Status != Microsoft.WindowsAzure.Storage.Blob.CopyStatus.Success)
                {
                    returnValue.Add(new CopyState()
                    {
                        BytesCopied = blob.CopyState.BytesCopied.GetValueOrDefault(),
                        TotalBytes = blob.CopyState.TotalBytes.GetValueOrDefault(),
                        Status = ToCopyStatus(blob.CopyState.Status),
                        Url = blob.Uri.ToString()
                    });
                }
            }

            return returnValue.ToArray();
        }

        //public CopyState GetCopyStatus(string blobUrl)
        //{
        //    ICloudBlob blob = _container.GetBlobReferenceFromServer(blobUrl);
        //    return new CopyState()
        //    {
        //        BytesCopied = blob.CopyState.BytesCopied.GetValueOrDefault(),
        //        TotalBytes = blob.CopyState.TotalBytes.GetValueOrDefault(),
        //        Status = CopyState.ToCopyStatus(blob.CopyState.Status)
        //    };
        //}

        public void RestartCopy(string url)
        {
            CloudBlockBlob blob = _container.GetBlockBlobReference(url);
            blob.StartCopyFromBlob(blob.CopyState.Source);
        }

        public CopyStatus ToCopyStatus(Microsoft.WindowsAzure.Storage.Blob.CopyStatus copyStatys)
        {
            switch (copyStatys)
            {
                case Microsoft.WindowsAzure.Storage.Blob.CopyStatus.Aborted:
                case Microsoft.WindowsAzure.Storage.Blob.CopyStatus.Failed:
                    return CopyStatus.Failed;
                case Microsoft.WindowsAzure.Storage.Blob.CopyStatus.Invalid:
                    return CopyStatus.Invalid;
                case Microsoft.WindowsAzure.Storage.Blob.CopyStatus.Pending:
                    return CopyStatus.Pending;
                case Microsoft.WindowsAzure.Storage.Blob.CopyStatus.Success:
                    return CopyStatus.Completed;
                default:
                    return CopyStatus.Invalid;
            }
        }

    }
}